package com.minigame.datastore;

import com.minigame.datastore.operation.OperationType;
import com.minigame.exception.GameDataOperationException;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityTransaction;
import org.springframework.data.jpa.repository.JpaRepository;

import java.io.Serializable;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class EntityDataStore<T,ID extends Serializable> {

    private JpaRepository<T,ID> jpaRepository;

    private Map<ID,T> priorityDeleteMap = new ConcurrentHashMap<>();

    private Map<ID,T> insertMap = new ConcurrentHashMap<>();

    private Map<ID,T> updateMap = new ConcurrentHashMap<>();

    private Map<ID,T> deleteMap = new ConcurrentHashMap<>();

    private List<T> dataList = new ArrayList<>();

    private List<ID> idList = new ArrayList<>();

    private String className;


    public EntityDataStore(JpaRepository<T,ID> jpaRepository, String className){
        this.jpaRepository = jpaRepository;
        this.className = className;
    }



    public void insert(ID id,T t){
        checkOperation(OperationType.INSERT,id);
        T oldt = deleteMap.get(id);
        //如果有删除的数据 这需要把删除转移到最高优先级
        if(oldt != null){
            deleteMap.remove(id);
            priorityDeleteMap.put(id,oldt);
        }
        insertMap.put(id,t);
    }

    public void update(ID id,T t){
        checkOperation(OperationType.UPDATE,id);
        T oldt = insertMap.get(id);
        //如果插入为空 则才加入到更新列表
        if(oldt == null){
            updateMap.put(id,t);
        }

    }


    /**
     * 执行删除 就需要把插入和更新数据都提前删除掉 加入待删除列表
     * */
    public void delete(ID id,T t){
        insertMap.remove(id);
        updateMap.remove(id);
        deleteMap.put(id,t);
    }

    public void checkOperation(OperationType operationType,ID id){
        switch (operationType){
            case DELETE:

                break;
            case INSERT:
            {
                T oldt = updateMap.get(id);
                if(oldt != null){
                    throw new GameDataOperationException("updateMap hava data,try insert operation need delete data first className="+className+" id="+id);
                }
            }
            break;
            case UPDATE:
            {
                T oldt = deleteMap.get(id);
                if(oldt != null){
                    throw new GameDataOperationException("data is deleted but now try update className="+className+" id="+id);
                }
            }
            break;
        }
    }

    public JpaRepository<T, ID> getJpaRepository() {
        return jpaRepository;
    }

    public void setJpaRepository(JpaRepository<T, ID> jpaRepository) {
        this.jpaRepository = jpaRepository;
    }

    public Map<ID, T> getPriorityDeleteMap() {
        return priorityDeleteMap;
    }

    public void setPriorityDeleteMap(Map<ID, T> priorityDeleteMap) {
        this.priorityDeleteMap = priorityDeleteMap;
    }

    public Map<ID, T> getInsertMap() {
        return insertMap;
    }

    public void setInsertMap(Map<ID, T> insertMap) {
        this.insertMap = insertMap;
    }

    public Map<ID, T> getUpdateMap() {
        return updateMap;
    }

    public void setUpdateMap(Map<ID, T> updateMap) {
        this.updateMap = updateMap;
    }

    public Map<ID, T> getDeleteMap() {
        return deleteMap;
    }

    public void setDeleteMap(Map<ID, T> deleteMap) {
        this.deleteMap = deleteMap;
    }

    public String getClassName() {
        return className;
    }

    public void setClassName(String className) {
        this.className = className;
    }

    public List<T> getDataList() {
        return dataList;
    }

    public void setDataList(List<T> dataList) {
        this.dataList = dataList;
    }

    public List<ID> getIdList() {
        return idList;
    }

    public void setIdList(List<ID> idList) {
        this.idList = idList;
    }
}
